/**
 * 
 */
package lablayer.model;

import java.util.*;

/**
 *
 */
public class LabData {
	private Double[][][] data;
	
	private boolean isNumber = false;
	
	private boolean isVector = false;
	
	private boolean isArray = false;
	
	/*
	 * convert List<Double> to Double[]
	 */
	protected static Double[] listToArray(List<Double> list) {
		try {
			assert list != null : "LabData.listToArray(List<Double> list) received null";
			
			Double[] array = new Double[list.size()];
			Iterator<Double> iter = list.iterator();
			int arrayIndex = 0;
			while(iter.hasNext()) {
				array[arrayIndex] = iter.next();
				arrayIndex++;
			}
			return array;
		} catch(Exception e) {
			return null;
		}		
	}
	               
	public LabData() {
		super();
	}
	
	public LabData(Double[][][] data) {
		try {
			assert data != null : "LabData(Double[][][] data) has received null data";
			this.data = data;
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

        public LabData(Double[] data) {
            try {
                this.data = new Double[1][][];
                this.data[0] = new Double[1][];
                this.data[0][0] = new Double[data.length];
                System.arraycopy(data, 0, this.data[0][0], 0, data.length);
            } catch (Exception e) {
                throw new UnsupportedOperationException();
            }
        }

        public LabData(Double data) {
            try {
                this.data = new Double[1][][];
                this.data[0] = new Double[1][];
                this.data[0][0] = new Double[1];
                this.data[0][0][0] = data;
            } catch (Exception e) {
                throw new UnsupportedOperationException();
            }
        }
	
	/*
	 * parse string to the Double[][] array
	 * 
	 * string format: 0.52,12.4,98;87,-9.4;0.0007,32,4,-87
	 */
	protected static Double[][] stringToArray(String string) {
		try {
			assert string != null : "LabData.parseString received null string";
						
			List<Double> numbers = new ArrayList<Double>();
			List<Double[]> rows = new ArrayList<Double[]>();
			String value = "";
			
			for(int i = 0; i < string.length(); i++) {				
				if(string.charAt(i) != ';') {
					if(string.charAt(i) != ',') {
						value += string.charAt(i);
					} else {
						numbers.add(new Double(value));
						value = "";
					}
				} else {
					numbers.add(new Double(value));
					value = "";										
					Double[] row = LabData.listToArray(numbers);					
					rows.add(row);
					numbers.clear();
				}
			}
			if(!(value.equals(""))) {
				numbers.add(new Double(value));
				value = "";				
				Double[] row = LabData.listToArray(numbers);
				rows.add(row);
				numbers.clear();
			}
			
			Double[][] array = new Double[rows.size()][];
			Iterator<Double[]> iter = rows.iterator();
			int i = 0;
			while(iter.hasNext()) {
				array[i] = iter.next();
				i++;
			}			
			return array;
		} catch (Exception e) {
			return null;
		}		
	}
	
	/*
	 * parse string to the Double[][][] array
	 * 
	 * string format: 0.52,12.4,98;87,-9.4;0.0007,32,4,-87:7.5,14.88
	 */
	public static Double[][][] parseString(String string) {
		try {
			assert string != null : "LabData.parseString(String) have a null pointer";
			
			List<Double[][]> arrays = new ArrayList<Double[][]>();
			String subString;
			int beginIndex = 0, endIndex;
			
			while(true) {
				endIndex = string.indexOf(":");
				if(endIndex == -1) {
					endIndex = string.length();
					break;
				}
				subString = string.substring(beginIndex, endIndex);
				arrays.add(LabData.stringToArray(subString));
				beginIndex = endIndex;
			}			
			subString = string.substring(beginIndex, endIndex);
			arrays.add(LabData.stringToArray(subString));
			
			Double[][][] result = new Double[arrays.size()][][];
			Iterator<Double[][]> arraysIterator = arrays.iterator();
			int resultIndex = 0;
			
			while(arraysIterator.hasNext()) {
				result[resultIndex] = arraysIterator.next();
				resultIndex++;
			}
			return result;
		} catch (Exception e) {
			return null;			
		}
	}
	
	/*
	 * 
	 */
        @Override
	public String toString() {
		String result = "";

                if (data != null) {
                    for(int i = 0; i < data.length; i++) {
                        for(int j = 0; j < data[i].length; j++) {
                            for(int k = 0; k < data[i][j].length; k++) {
                                result += data[i][j][k];
                                if (k != (data[i][j].length) - 1) {
                                    result += ',';
                                }
                            }
                            if (j != (data[i].length - 1)) {
                                result += ';';
                            }
                        }
                        if (i != (data.length - 1)) {
                            result += ':';
                        }
                    }
                }
		return result;
	}
	
	/*
	 * if data have only one value, isNumber return true
	 */
	public boolean isNumber() {
		try {
			assert this.data != null : "LabData.data is null";
			if(data.length == 1) {
				Double[][] array = data[0];
				if(array.length == 1) {										
					Double[] row = array[0];
					if(row.length == 1) {
						this.isNumber = true;
					} else {
						this.isNumber = false;
					}
				} else {
					this.isNumber = false;
				}
			} else {
				this.isNumber = false;
			}
		} catch (Exception e) {
			this.isNumber = false;
		}
		return isNumber;
	}
	
	/*
	 * if data have one row, isVector return true
	 */
	public boolean isVector() {
		try {
			assert this.data != null : "LabData.data is null";
			if(data.length == 1) {
				Double[][] array = data[0];
				if(array.length == 1) {
					Double[] row = array[0];
					if(row.length != 1) {
						this.isVector = true;
					} else {
						this.isVector = false;
					}
				} else {
					this.isVector = true;
				}
			} else {
				this.isVector = false;
			}
		} catch (Exception e) {
			this.isVector = false;
		}
		return isVector;
	}

	public boolean isArray() {
		try {
			assert this.data != null : "LabData.data is null";
			if(data.length == 1) {
				this.isArray = false;
			} else {
				this.isArray = true;
			}
		} catch (Exception e) {
			this.isArray = false;
		}
		return isArray;
	}

	public Double[][][] getData() {
		return data;
	}
	
	public void setData(Double data) {
		try {
			assert data != null : "LabData.setData(Double) have a null pointer";
			this.data = null;
			this.data = new Double[1][][];
			this.data[0] = new Double[1][];
			this.data[0][0] = new Double[1];
			this.data[0][0][0] = data;
		} catch (Exception e) {
			//process exception here
		}
	}
}
